TwitchClone / src / pages / [userEmail].tsx
[userEmail].tsx
Raw
import { useSession } from "next-auth/react";
import { useRouter } from "next/router";
import Link from "next/link";
import { SetStateAction, useEffect, useRef, useState } from "react";
import { useRoomDataContext } from "../utils/context/RoomDataContext";
import { UserSchema } from "../types/user";
// import StreamPage from "./streamPage";
import { api } from "../utils/api";
import { NextPage } from "next";
import { getStoredData } from "../utils/helpers/getStoredData";
import Chat from "../components/chatTwo";
import VideoPlayer from "../components/videoPlayer";
// import { Video } from "@mux/mux-node/dist/video/video";
import { Content, User, UserFollows } from "@prisma/client";
import { filteredVids } from "../utils/helpers/filterOldVids";
import { FollowButton } from "../components/buttons/followUserButton";
import Navbar from "../components/navbar/navbarParent";
// import { handleFollow } from "../utils/helpers/handleFollow";
import { RoomDataSchema } from "../types/roomData";
import userToUserProfile from "../utils/helpers/userToUserProfile";
import { useUser } from "../hooks/useUser";
import { handleClick } from "../utils/helpers/pmTab";
import {
  handleTitleBlur,
  handleTitleChange,
  handleTitleKeyPress,
} from "../utils/helpers/handleTitle";
import CollapseChatSvg from "../components/svgs/collapseChat";
import classNames from "../utils/helpers/className";
import ExpandChatSvg from "../components/svgs/expandChat";
import { Transition } from "@headlessui/react";
// import NavbarSection from "react-daisyui/dist/Navbar/NavbarSection";
type StreamerInfo = User & {
  videos: Content[];
  following: UserFollows[];
  followers: UserFollows[];
};

const Room: NextPage = () => {
  const { data: user, status } = useSession();
  const router = useRouter();
  const { userEmail } = router.query;
  const [streamName, setStreamName] = useState("");
  const { roomData, setRoomData, userData, setUserData } = useRoomDataContext();
  const [hoveredVideo, setHoveredVideo] = useState<null | Content>(null);
  const [allVids, setAllVids] = useState<Content[] | null>(null);
  const [selectedVideo, setSelectedVideo] = useState<null | Content>(null);
  const [streamTitle, setStreamTitle] = useState("Stream Title");
  const streamerData = api.lambda.getUserById.useQuery({
    id: userEmail as string,
  });
  const userDbData = api.lambda.getUserInfo.useQuery({
    email: userEmail as string,
  });
  const [chatUser, setChatUser] = useState<null | UserSchema>(null);
  const [authedAccount, setAuthedAccount] = useState<null | UserSchema>(null);
  const [isEditingTitle, setIsEditingTitle] = useState(false);
  const updateFollowingMutation = api.lambda.updateFollowing.useMutation();
  const inputRef = useRef(null);
  const userP = useUser();
  const [navOpened, setNavOpened] = useState(false);
  const [chatExpand, setChatExpand] = useState(true);
  const [searchTab, setSearchTab] = useState(false);
  const updateTitleMutation = api.lambda.updateVideo.useMutation();
  const [roomId, setRoomId] = useState<null | string | string[]>(null);

  useEffect(() => {
    console.log("no", userEmail, roomId);
    if (userEmail && roomId === null) {
      setRoomId(userEmail);
    }
  }, [userEmail, roomId]);
  //test

  const mobileSearchProps = {
    opened: navOpened,
    handleClick: handleClick,
    searchTab,
    setSearchTab,
  };
  const userProfile_ = userToUserProfile(userP);
  // Check if the current user is the owner of the page
  const isOwner =
    user && user.user && userEmail === user.user.email ? true : false;

  console.log("streamerData", streamerData);
  console.log("streamName", streamName);
  if (streamerData.data && roomData?.streamerInfo !== streamerData.data) {
    setRoomData((prevRoomData) => {
      if (!prevRoomData) {
        return null;
      }
      return {
        ...prevRoomData,
        streamerInfo: streamerData.data,
      };
    });

    if (allVids == null) {
      console.log(
        "streamerData.data.videos",
        filteredVids(streamerData.data.videos)
      );
      if (filteredVids(streamerData.data.videos).length > 0) {
        setAllVids(filteredVids(streamerData.data.videos));
      }
    }
  }
  console.log("streamerData.data", streamerData.data);

  useEffect(() => {
    if (userEmail && streamName !== userEmail) {
      setStreamName(userEmail as string);
    }
  }, [userEmail, streamName, router.asPath, allVids, user]);

  console.log(roomData, userData, "roomData, userData");

  const [localRoomData, setLocalRoomData] = useState<null | typeof roomData>(
    null
  );
  const [localUserData, setLocalUserData] = useState<null | UserSchema>(null);
  console.log(localUserData, localRoomData, "localUserData, localRoomData");

  // Set focus and select the text when the input appears
  //  useEffect(() => {
  //     if (isEditingTitle && inputRef.current) {
  //       inputRef.current.focus();
  //       inputRef.current.select();
  //     }
  //   }, [isEditingTitle]);
  useEffect(() => {
    if (userDbData && userDbData.data) {
      console.log("change", userDbData.data);
      setChatUser(userDbData.data);
    }
  }, [userDbData]);

  // const handleEditTitle = () => {
  //   setIsEditingTitle(true);
  // };

  // // const handleTitleChange = (e: any ) => {
  // const handleTitleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  //   setStreamTitle(e.target.value);
  // };

  // const handleTitleBlur = () => {
  //   setIsEditingTitle(false);
  // };

  // // const handleTitleKeyPress = (e: any) => {
  // const handleTitleKeyPress = (e: React.KeyboardEvent<HTMLInputElement>) => {
  //   if (e.key === "Enter") {
  //     setIsEditingTitle(false);
  //   }
  // };

  useEffect(() => {
    console.log("localUserData", localUserData);

    if (chatUser != localUserData) {
      console.log("change", chatUser, localUserData);
      setChatUser(localUserData);
    }
    if (streamName) {
      if (localRoomData === null) {
        const initialLocalRoomData = getStoredData(`roomData-${streamName}`);
        setLocalRoomData(initialLocalRoomData as RoomDataSchema);
      }

      if (localUserData === null) {
        const initialLocalUserData = getStoredData("userData");
        setLocalUserData(initialLocalUserData as UserSchema);
      }
    }

    if (!roomData && localRoomData && user && user.user) {
      setRoomData(localRoomData);
      setAuthedAccount(user.user);
    } else if (roomData && !localRoomData && user && user.user) {
      setLocalRoomData(roomData);
      setAuthedAccount(user.user);
      localStorage.setItem(`roomData-${streamName}`, JSON.stringify(roomData));
    } else if (!roomData && !localRoomData && user && user.user) {
      const storedRoomData = getStoredData(`roomData-${streamName}`);
      if (storedRoomData) {
        setRoomData(storedRoomData as RoomDataSchema);
        setLocalRoomData(storedRoomData as RoomDataSchema);
        setAuthedAccount(user.user);
      }
    }

    if (!userData && localUserData) {
      setUserData(localUserData);
    } else if (userData && !localUserData) {
      setLocalUserData(userData);
      localStorage.setItem("userData", JSON.stringify(userData));
    } else if (!userData && !localUserData) {
      const storedUserData = getStoredData("userData");
      if (storedUserData) {
        setUserData(storedUserData as UserSchema);
        setLocalUserData(storedUserData as UserSchema);
      }
    }
  }, [roomData, localRoomData, streamName, userData, localUserData, chatUser]);

  const handleChatExpand = () => {
    setChatExpand(!chatExpand);
  };

  const updateLocalData = (newData: UserSchema) => {
    // Update localUserData
    setLocalUserData(newData);

    // Update userData
    setUserData(newData);

    // Update localRoomData with the latest userData
    setLocalRoomData((prevLocalRoomData) => {
      if (prevLocalRoomData) {
        return {
          ...prevLocalRoomData,
          userData: newData,
        };
      }
      return prevLocalRoomData;
    });

    // Update roomData with the latest userData
    setRoomData((prevRoomData) => {
      if (prevRoomData) {
        return {
          ...prevRoomData,
          userData: newData,
        };
      }
      return prevRoomData;
    });

    // Store the updated data in localStorage
    localStorage.setItem("userData", JSON.stringify(newData));
    localStorage.setItem(
      `roomData-${userEmail as string}`,
      JSON.stringify(roomData)
    );
  };

  const userProfile =
    user && user.user
      ? {
          id: user.user.id,
          username: user.user.name,
          // Add other properties as needed
        }
      : undefined;
  console.log(userProfile, "userProfile");
  console.log(streamName, "streamName");
  console.log(localRoomData, "localRoomData");
  console.log(localRoomData?.userData, "localRoomData?.userData");
  console.log("localRoomData?.assetData", localRoomData?.assetData);
  if (
    (!userProfile ||
      !streamName ||
      !localRoomData ||
      !localRoomData.userData ||
      !localRoomData.assetData ||
      localRoomData.assetData.userId === null) &&
    !user
  ) {
    console.log("userProfile", userProfile);
    console.log("streamName", streamName);
    console.log("localRoomData", localRoomData);
    console.log("localRoomData.userData", localRoomData?.userData);
    console.log("localRoomData.assetData", localRoomData?.assetData);
    console.log(
      "localRoomData.assetData.userId",
      localRoomData?.assetData?.userId
    );

    return (
      <div>
        You need to be logged in to view this page . <br />
        <Link href="/signin">
          <p>Sign in</p>
        </Link>
      </div>
    );
  }
  // const roomId =
  //   localRoomData?.assetData?.userId ||
  //   roomData?.assetData?.userId ||
  //   localUserData?.email;

  console.log("roomId", roomId);
  console.log(localRoomData, "localRoomData");
  console.log(localRoomData?.userData, "localRoomData?.userData");
  console.log(localRoomData?.assetData, "localRoomData?.videoData");
  console.log("allVids", allVids);
  console.log(chatExpand, "chatExpand");
  return (
    // <div className="flex flex-col items-center justify-center">

    <div className=" max-w-screen flex max-h-screen flex-col bg-[#0e0e10] text-base">
      {/* <h1 className="h-full w-full">Room: {streamName || "Unknown Room"}</h1> */}
      {/* <NavbarSection /> */}
      {/* <Navbar 
      />  */}
      <div className="top-0 z-30 max-h-[3.00rem]  md:min-h-full">
        <Navbar
          profile={userProfile_}
          mobile={false}
          search={false}
          customCombo={false}
          props={mobileSearchProps}
        />
      </div>
      <div className=" flex justify-center">
        {/* don't change 'h' */}
        <div className="flex h-[calc(100vh-2.45rem)] w-full flex-col overflow-scroll scrollbar-hide">
          <div className="group flex min-h-[50vh] w-full items-center justify-center border-2 border-red-500 bg-black pt-2">
            {selectedVideo && (
              <VideoPlayer
                videoData={selectedVideo}
                isLoading={!selectedVideo}
                playbackId={selectedVideo.playbackId}
              />
            )}
            <div
              onClick={handleChatExpand}
              className={classNames(
                chatExpand ? " " : "group-hover:visible group-hover:flex",
                "invisible absolute top-[2.8rem] right-[1.5rem] cursor-pointer fill-white"
              )}
            >
              <ExpandChatSvg />
            </div>
          </div>
          <div className="flex w-full flex-col items-center">
            <div className="flex w-full items-center justify-between">
              <h2 className="text-2xl">
                {isEditingTitle && selectedVideo ? (
                  <input
                    ref={inputRef}
                    value={streamTitle}
                    onChange={(e) => handleTitleChange(e, setStreamTitle)}
                    onBlur={
                      void handleTitleBlur(
                        selectedVideo.userId,
                        setIsEditingTitle,
                        streamTitle,
                        selectedVideo.playbackId,
                        selectedVideo.id,
                        updateTitleMutation
                      )
                    }
                    autoFocus={true}
                    onKeyDown={(e) => handleTitleKeyPress(e, setIsEditingTitle)}
                  />
                ) : (
                  <h1 className="pt-4 pb-[5.8rem]">{streamTitle}</h1>
                )}
              </h2>
              {!isOwner && localRoomData && (
                <FollowButton
                  followId={streamerData.data?.id || ""}
                  isFollowing={
                    localUserData?.following?.some(
                      (followId) =>
                        followId.followingId === streamerData.data?.id
                    ) || false
                  }
                  userProfile_={localRoomData.userData}
                  updateLocalData={updateLocalData}
                  setLocalUserData={setLocalUserData}
                  roomData={localRoomData}
                  setUserData={setUserData}
                  updateFollowingMutation={updateFollowingMutation}
                />
              )}
            </div>
            {isOwner && (
              <div>
                {/* Render edit options */}
                <button>Edit Title</button>
                <button>Edit Description</button>
              </div>
            )}
            <div className=" w-full">
              {allVids &&
                allVids.map((video) => (
                  <div
                    key={video.id}
                    className={`cursor-pointer ${
                      hoveredVideo === video
                        ? "w-[7rem] border-4 border-blue-600"
                        : "w-[7rem]"
                    }`}
                    onMouseEnter={() => setHoveredVideo(video)}
                    onMouseLeave={() => setHoveredVideo(null)}
                    onClick={() => setSelectedVideo(video)}
                  >
                    <img
                      src={`https://image.mux.com/${video.playbackId}/thumbnail.jpg`}
                      alt={video.streamKey}
                    />
                  </div>
                ))}
            </div>
          </div>
        </div>
        <div
          className={classNames(
            chatExpand ? "flex" : "hidden",
            "min-h-[calc(100vh-2.45rem)] w-full"
          )}
        >
          {/* <Transition
          show={chatExpand}
          enter="transition ease-in-out duration-500 transform"
          enterFrom="translate-x-full"
          enterTo="translate-x-0"
          leave="transition ease-in-out duration-500 transform"
          leaveFrom="translate-x-0"
          leaveTo="translate-x-full"
        >  */}
          {/* {roomId !== null ? ( */}
          {roomId !== null && (
            <Chat
              roomId={roomId as string}
              streamerData={roomData?.streamerInfo as StreamerInfo}
              chatExpand={chatExpand}
              handleChatExpand={handleChatExpand}
            />
          )}
          {/* //  : localRoomData !== null &&
          //   localRoomData.assetData &&
          //   localRoomData.assetData.userId ? (
          //   <Chat
          //     roomId={localRoomData.roomId as string}
          //     streamerData={roomData?.streamerInfo}
          //     chatExpand={chatExpand}
          //     handleChatExpand={handleChatExpand}
          //   />
          // ) : (
          //   <Chat
          //     roomId={localUserData?.email as string}
          //     streamerData={roomData?.streamerInfo}
          //     chatExpand={chatExpand}
          //     handleChatExpand={handleChatExpand}
          //   />
          // )} */}
          {/* </Transition> */}
        </div>
        {/* // Example video list rendering */}
      </div>
    </div>
  );
};

export default Room;